// 配置axios基本请求
import axios from "axios";
import { Message } from "element-ui";
import router from "@/router";
import { removeToken } from "@/utils/auth";
import qs from "qs";
import {AES_CBC_ENCRYPT} from "@/utils/auth"
import config1 from "@/config/index"
// 设置默认Error对象
const ErrorParam = {
    alterMessage: false,
    message: "",
    otherMessage: "",
    gotoLogin: false,
    ignoreCode: [],
    ignoreFalse: false
};

// token失效时，跳转登录页
function toLogin(data) {
    removeToken();
    router.push({
        path: "/login",
        query: {
            redirect: location.href.replace(location.origin + "/admin", "")
        } // 如果你使用钩子函数，your path 可以替换成to.fullPath
    });
    return Promise.reject(data);
}

// 跳转系统维护页面
function toSystem(data) {}

// 全局打印异常
export const fetchErrorMessage = (
    error,
    alterMessage = true, // 是否提示异常
    message, // -1情况下的异常自定义提示
    otherMessage, // 其他情况下的自定义提示
    ignoreCode = [] // 忽略处理的code列表
) => {
    if (ignoreCode && ignoreCode.includes(error.code)) {
        return;
    }
    if (alterMessage) {
        if ((message || otherMessage) && error.code === -1) {
            Message.error(message || otherMessage || error.message);
        } else if (otherMessage) {
            Message.error(otherMessage);
        } else if (error.code === 11000) {
            Message.error("您操作过于频繁，请稍后再试");
        } else {
            Message.error(error.message);
        }
    }
};

// 检查返回数据的code值
function errorCheck(config, data, errorData) {
    if (data.code === 1) {
        // 在返回boolean值情况下 返回false认为失败
        if (errorData.ignoreFalse) {
            return Promise.resolve(data.data);
        }
        if (data.data !== false) {
            return Promise.resolve(data.data);
        }
        return Promise.reject(data);
    } else if (data.code === 1000) {
        return toLogin(data);
    } else if (data.code === 103 || data.code === 102 || data.code === 101) {
        if (errorData.gotoLogin) {
            // token 无效or不存在 跳转登录页
            return toLogin(data);
        } else {
            return Promise.reject(data);
        }
    } else if (data.code === 1000) {
        return toLogin(data);
    } else if (data.code === 100) {
        // 跳转系统维护页面
        return toSystem(data);
    }
    fetchErrorMessage(
        data,
        errorData.alterMessage,
        errorData.message,
        errorData.otherMessage,
        errorData.ignoreCode
    );
    return Promise.reject(data);
}

const getHost = () => {
    return "yun.caishi.cn";
};
// 配置基本请求信息
export const request = async (config, errorMsg) => {
    errorMsg = {
        gotoLogin: true,
        ...(errorMsg || {})
    };

    return axios
        .request({
            baseURL: "/api/yuntk",
            ...config,
            headers: {
                platform: "yuntiku",
                dt: "admin",
                ht: getHost(),
                timestamp: new Date().getTime(),
                gId: AES_CBC_ENCRYPT("6",config1.aes_key),
                ...config.headers
            }
        })
        .catch(e => {
            if (e.toString().includes("code 403") && errorMsg.v403 !== false) {
                router.push({
                    path: "/403"
                });
            }
            throw e;
        })
        .then(res => {
            return res.data;
        })
        .then(data => {
            return errorCheck(config, data, errorMsg);
        });
};

/**
 * get请求
 * @param input url路径或者{@see AxiosRequestConfig}
 * @param param 请求参数 会自动序列话到url?key=value的形式
 */
export const get = async (url, params = {}, errorMsg) => {
    return request(
        {
            url,
            params,
            method: "GET",
            paramsSerializer: data =>
                qs.stringify(data, { arrayFormat: "repeat" })
        },
        errorMsg
    );
};

/**
 * post请求
 * @param {*} url
 * @param {*} param
 * @param {*} errorMsg
 */
export const post = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "POST",
            data: params,
            headers: {
                // ...req.headers,
                "Content-Type": "application/json"
            }
        },
        errorMsg
    );
};

/**
 * postJson
 * @param {*} url
 * @param {*} param
 * @param {*} errorMsg
 */
export const postForm = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "POST",
            data: objCoverFormData(params),
            headers: {
                "Content-Type": "multipart/form-data"
            }
        },
        errorMsg
    );
};

/**
 *
 * @param {*} input
 * @param {*} param
 * @param {*} errorMsg
 */
export const put = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "PUT",
            data: params
        },
        errorMsg
    );
};
export const putForm = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "PUT",
            data: objCoverFormData(params),
            headers: {
                "Content-Type": "multipart/form-data"
            }
        },
        errorMsg
    );
};

export const fetchDelete = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "DELETE",
            data: params
        },
        errorMsg
    );
};

export const fetchDeleteForm = (url, params, errorMsg) => {
    return request(
        {
            url,
            method: "DELETE",
            data: objCoverFormData(params),
            headers: {
                "Content-Type": "multipart/form-data"
            }
        },
        errorMsg
    );
};

export function flagPromise(fetchPromise, flag) {
    if (flag) {
        this.flag[flag] = true;
    }
    return fetchPromise
        .then(r => r)
        .finally(() => {
            if (flag) {
                this.flag[flag] = false;
            }
        });
}

function objCoverFormData(params) {
    let formData = new FormData();
    if (params) {
        for (let k in params) {
            if (Array.isArray(params[k])) {
                // 遍历数组
                params[k].forEach((obj,index) => {
                    // 遍历对象的所有属性
                    for (let key in obj) {
                        // 检查是否为对象自身的属性（不包括原型链上的属性）
                        if (Object.prototype.hasOwnProperty.call(obj, key)) {
                            // 构建属性名和属性值的字符串，并添加到 displayString 中
                            formData.append(k+"["+index+"]."+key,obj[key]);
                        }
                    }
                });

                continue;
            }
            if (typeof params[k] === typeof {}) {
                continue;
            }
            if (params[k] === null || params[k] === undefined) {
                continue;
            }
            formData.append(k, params[k]);
        }
    }
    return formData;
}

export default {
    request,
    get,
    post,
    put,
    fetchDelete,
    delete: fetchDelete,
    flagPromise
};
